﻿// ------------------------------------------------------------------------------------------------
//  <copyright file="Drafttor.cs" company="Iveely">
//    Copyright (c) Iveely Liu.  All rights reserved.
//  </copyright>
//  
//  <Create Time>
//    12/03/2012 20:12 
//  </Create Time>
//  
//  <contact owner>
//    liufanping@iveely.com 
//  </contact owner>
//  -----------------------------------------------------------------------------------------------

#region

using System;
using System.Collections;
using System.Collections.Generic;
using IveelySE.NLP.Common.DataStructure;
using System.IO;

#endregion

namespace IveelySE.NLP.Knowledge.Extraction
{
    /// <summary>
    ///   初稿生成器
    /// </summary>
    public class Drafttor
    {
        #region 属性 OR 字段

        /// <summary>
        ///   文本标识分割符
        /// </summary>
        private static readonly char[] Separator = { '.', '!', '?', '。', '！', '？' };

        /// <summary>
        ///   初稿箱（当前初稿容器）
        /// </summary>
        public static readonly List<Draft> CurrentContainer = new List<Draft>();

        /// <summary>
        ///   初稿箱（全局初稿容器）
        /// </summary>
        private static Hashtable GlobalContainer = new Hashtable();


        #endregion

        #region 方法

        /// <summary>
        ///   增添初稿
        /// </summary>
        /// <param name="docId"> 初稿所在文档编号</param>
        /// <param name="draf"> 初稿对应的问题 </param>
        private static void Add(int docId, StateQueue draf)
        {
            //建立一个初稿
            var dr = new Draft();
            //添加初稿信息
            dr.Add(docId, draf[0], draf[1], draf[2]);
            CurrentContainer.Add(dr);
            GlobalContainer.Add(docId, dr);
        }

        /// <summary>
        ///   创建初稿
        /// </summary>
        /// <param name="context"> 初稿所在的上下文 </param>
        /// <param name="docId"> 初稿文档编号</param>
        public static List<StateQueue> Create(string context, int docId = 1)
        {
            if (GlobalContainer.Count == 0 && File.Exists(Config.Application.GetEventFile()))
            {
                GlobalContainer = (Hashtable)IveelySE.Common.Serialize.UnSerailzable(Config.Application.GetEventFile());
            }
            var result = new List<StateQueue>();
            CurrentContainer.Clear();

            //将上下文按照分割符切分成句子
            string[] sentences = context.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
            //将每一个初稿匹配模式取出进行匹配
            foreach (var pattern in Pattern.GetInstance().Draft)
            {
                HashSet<string> notInclude;
                int si = pattern.IndexOf('|');
                string pat = pattern.Substring(0, si);
                notInclude = new HashSet<string>(pattern.Substring(si + 1, pattern.Length - si - 1).Split(','));
                //依次对每一个句子做处理
                foreach (var sentence in sentences)
                {
                    //利用状态队列来实现初稿提取
                    var sq = new StateQueue();
                    //将找匹配模式分割符号，切分分割符
                    string[] ps = pat.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries);
                    //将原有的文本按照pattern进行分词
                    var source = new List<string>(sentence.Split(ps, StringSplitOptions.RemoveEmptyEntries));
                    //补全分完后文本的原始数组（因为Split分割会将分割符丢弃）
                    int j = 0;
                    for (int i = 0; i < ps.Length; i++)
                    {
                        try
                        {
                            source.Insert(i + 1 + j++, ps[i]);
                        }
                        catch
                        {
                            sq.Clean();
                        }
                    }
                    //将处理后的文本加入到状态队列中去，标记为0
                    sq.Add(source.ToArray(), 0);
                    //将pattern的字符数据也加入到状态队列中去，标记为1
                    sq.Update(ps, 1);
                    //遍历
                    if (sq.Count() > 2 && !notInclude.Contains(sq[0].ToCharArray()[sq[0].Length - 1].ToString()))
                    {
                        Add(docId, sq);
                        result.Add(sq);
                    }
                }
            }

            IveelySE.Common.Serialize.Serailzable(GlobalContainer, Config.Application.GetEventFile());
            return result;
        }

        #endregion

        #region 测试

        public static void Test(string text)
        {
            List<StateQueue> result = Create(text);
            foreach (var stateQueue in result)
            {
                Console.Write(stateQueue[0] + " ==>" + stateQueue[1] + "<== " + stateQueue[2]);
                Console.WriteLine("\n---------------------------------------------\n");
            }
        }

        #endregion
    }
}